/*
 * QTXpost - a Qt-based blog client.
 * Copyright (C) 2010 Helen Sommer
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (in COPYING); if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA  02111-1307  USA
 *
 * The project is hosted on http://code.google.com/p/qtxpost
 */

#include "MainWindow.h"
#include "ServerConfig.h"

extern MainWindow *root;

ServerConfig::ServerConfig(QWidget *parent) 
  : QDialog(parent)
{
  setupUi(this);

  /*mainGridLayout->setColumnStretch(0, 2); // how to do it in Designer??
  mainGridLayout->setColumnStretch(1, 4); */
  

  serverTypeCombo->addItem("LJ-based");
  serverTypeCombo->addItem("DW-based");
  
  connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteServer()));
  connect(updateButton, SIGNAL(clicked()), this, SLOT(updateServer()));
  connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
  connect(upButton, SIGNAL(clicked()), this, SLOT(upServer()));
  connect(downButton, SIGNAL(clicked()), this, SLOT(downServer()));

  connect(hiddenToggle, SIGNAL(stateChanged(int)), this, SLOT(hideServer(int)));
  connect(forceIconsToggle, SIGNAL(stateChanged(int)), this, SLOT(forceUpdate(int)));
  connect(updateIconsToggle, SIGNAL(stateChanged(int)), this, SLOT(updateIcons(int)));

  serversButtonGroup = new QButtonGroup();
  connect(serversButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(toggleServer(int)));
  maxButtonGroupId = 0;

  QSqlQuery query;
  query.exec("select label, hidden from users order by position");
  while (query.next()) {
    QString label = query.value(0).toString();
    bool hidden = query.value(1).toInt();

    QRadioButton *serverLabel = new QRadioButton(label);
    QFont font = serverLabel->font();
    font.setItalic(hidden);
    serverLabel->setFont(font);

    layoutFrame->addWidget(serverLabel, 1);
    serversButtonGroup->addButton(serverLabel);
    serversButtonGroup->setId(serverLabel, maxButtonGroupId++);
  }
  
  addNewAccount = new QRadioButton(tr("[add new account]"));
  layoutFrame->addWidget(addNewAccount, 1);
  serversButtonGroup->addButton(addNewAccount);
  serversButtonGroup->setId(addNewAccount, -1);
  if (maxButtonGroupId == 0) {
    addNewAccount->setChecked(true);
    toggleServer(-1);
  }

  layoutFrame->insertStretch(-1,4);
  
  currentCursor = cursor();
}

void ServerConfig::toggleServer(int id)
{
  if (id >= 0) {
    labelLine->setText(root->servers.at(id)->label);
    usernameLine->setText(root->servers.at(id)->username);
    passwordLine->setText(root->servers.at(id)->password);
    serverLine->setEditText(root->servers.at(id)->server);
    hiddenToggle->setChecked(root->servers.at(id)->hidden);
    serverTypeCombo->setCurrentIndex(root->servers.at(id)->serverType);
  }
  else { // new account
    labelLine->setText("new account");
    usernameLine->clear();
    passwordLine->clear();
    serverLine->setEditText("newserver.com");
    hiddenToggle->setChecked(false);
    updateIconsToggle->setChecked(true);
    updateMoodsToggle->setChecked(true);
    serverTypeCombo->setCurrentIndex(LJ_TYPE);
  }
  progressBar->reset();
  progressBar->hide();
}

void ServerConfig::updateServer()
{
  int id = serversButtonGroup->checkedId();
  
  if (id < 0) {
    id = addServer();
  }

  if (id >= 0) {
    root->servers.at(id)->update(
                                 usernameLine->text(),
                                 passwordLine->text(),
                                 labelLine->text(),
                                 serverLine->currentText(),
                                 serverTypeCombo->currentIndex(),
                                 updateIconsToggle->isChecked(),
                                 forceIconsToggle->isChecked(),
                                 updateMoodsToggle->isChecked());
    serversButtonGroup->button(id)->setText(labelLine->text());
  }
  root->updateMoods();
}

void ServerConfig::reorderServers()
{
  QRadioButton *checked = (QRadioButton *)serversButtonGroup->checkedButton();
  QString checkedName = checked->text();
  root->reorderServers();

  QList<QAbstractButton *> buttons = serversButtonGroup->buttons();
  int k = 0; 
  // can't use the same index for root->servers 
  // because then the lookup fails on adding new account (should be fixed?)
  for (int i = 0; i < buttons.size(); i++) {
    QRadioButton *button = (QRadioButton *)buttons.at(i);
    //    if (button->text() == "[add new account]") continue;
    if (button == addNewAccount) continue;
    QString label = root->servers.at(k)->label;
    button->setText(label);
    if (label == checkedName) 
      button->setChecked(true); // the checked button might jump to another position
    QFont font = button->font();
    font.setItalic(root->servers.at(k)->hidden);
    button->setFont(font);
    k++;
  }
}

int ServerConfig::addServer()
{
  QSqlQuery query;
  QString command; 
  QMessageBox msgBox;
  QString error;

  // verify parameters
  if (usernameLine->text() == "" || passwordLine->text() == "" || 
      labelLine->text() == "" || serverLine->currentText() == "") {
    error = QString(tr("Some of required parameters (username, password, label, server) are empty!"));
    msgBox.setText(error);
    msgBox.setIcon(QMessageBox::Warning);
    msgBox.exec();
    return -1;
  }
  // check if this label already exists
  command = QString("select username,server from users where label=\"%1\"").arg(labelLine->text());
  query.exec(command);
  if (query.next()) {
    QString username = query.value(0).toString();
    QString server = query.value(1).toString();
    error = QString(tr("Label %1 is already used (for username %2, server %3).\nPlease choose a different label.")).arg(labelLine->text()).arg(username).arg(server);
    msgBox.setText(error);
    msgBox.setIcon(QMessageBox::Warning);
    msgBox.exec();
    return -1;
  }

  // everything ok, add the server
  root->addServer(usernameLine->text(), passwordLine->text(), labelLine->text(), serverLine->currentText(), serverTypeCombo->currentIndex());
  // remove spacer and the last button
  for (int i = 0; i < layoutFrame->count(); i++) {
    if (layoutFrame->itemAt(i)->spacerItem() || (QRadioButton *)layoutFrame->itemAt(i) == addNewAccount) {
      layoutFrame->takeAt(i);
    }
  }
  // add back to the end [add new account] and spacer
  QRadioButton *serverLabel = new QRadioButton(labelLine->text());
  serverLabel->setChecked(true);
  serversButtonGroup->addButton(serverLabel);
  serversButtonGroup->setId(serverLabel, maxButtonGroupId++);
  layoutFrame->addWidget(serverLabel, 1);
  layoutFrame->addWidget(addNewAccount, 1);
  layoutFrame->insertStretch(-1, 4);

  return (maxButtonGroupId - 1);
}

void ServerConfig::deleteServer()
{
  QMessageBox msgBox;
  
  int id = serversButtonGroup->checkedId();
  if (id < 0) return;

  QString message = QString(tr("Really delete %1 (username %2, server %3)?")).arg(root->servers.at(id)->label).arg(root->servers.at(id)->username).arg(root->servers.at(id)->server);
  msgBox.setText(message);
  msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
  msgBox.setDefaultButton(QMessageBox::No);
  if (msgBox.exec() == QMessageBox::Yes) {
    root->servers.at(id)->deleteServer();
    QRadioButton *button = (QRadioButton *)serversButtonGroup->checkedButton();
    button->hide();
    serversButtonGroup->removeButton(button);
    addNewAccount->setChecked(true);
    toggleServer(-1);
  }
}

void ServerConfig::initializeProgress()
{
  progressBar->show();
  progressBar->setValue(1);
  
  setCursor(Qt::WaitCursor);
}

void ServerConfig::initializeProgress(int target_)
{
  target = target_;
  count = 0;
  step = 100/target;
  initializeProgress();
}

void ServerConfig::incrementProgress()
{
  count++;
  progressBar->setValue(progressBar->value() + step);
  if (count >= target) 
    completeProgress();
}

void ServerConfig::completeProgress()
{
  progressBar->setValue(100);
  setCursor(currentCursor);
}

void ServerConfig::hideServer(int)
{
  int id = serversButtonGroup->checkedId();
  if (id < 0) return;

  QRadioButton *button = (QRadioButton *)serversButtonGroup->checkedButton();
  bool hidden = hiddenToggle->isChecked();
  root->servers.at(id)->hideServer(hidden);
  QFont font = button->font();
  font.setItalic(hidden);
  button->setFont(font);
}

void ServerConfig::forceUpdate(int)
{
  if (forceIconsToggle->isChecked()) {
    updateIconsToggle->setChecked(true);
  }
}

void ServerConfig::updateIcons(int)
{
  if (!updateIconsToggle->isChecked()) {
    forceIconsToggle->setChecked(false);
  }
}

void ServerConfig::upServer()
{
  int id = serversButtonGroup->checkedId();
  if (id <= 0) return;
  int position = root->servers.at(id-1)->position;
  root->servers.at(id-1)->updatePosition(root->servers.at(id)->position);
  root->servers.at(id)->updatePosition(position);
  reorderServers();
}

void ServerConfig::downServer()
{
  int id = serversButtonGroup->checkedId();
  if (id == -1 || id >= root->servers.size() - 1) return;
  int position = root->servers.at(id+1)->position;
  root->servers.at(id+1)->updatePosition(root->servers.at(id)->position);
  root->servers.at(id)->updatePosition(position);
  reorderServers();
}

